package org.snail.spring.boot.util;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.Objects;

/**
 * @author MR.LHL
 * @date 2023/7/25
 */
public class GsonUtil {

    private static final Gson gson = new Gson();

    public static JsonObject mergeJsonObjects(JsonObject... jsonObjects) {
        JsonObject mergedJsonObject = new JsonObject();
        for (JsonObject jsonObject : jsonObjects) {
            for (String key : jsonObject.keySet()) {
                mergedJsonObject.add(key, jsonObject.get(key));
            }
        }
        return mergedJsonObject;
    }

    /**
     * 合并JsonArray
     *
     * @param jsonArrays
     * @return
     */
    public static JsonArray mergeJsonArrays(JsonArray... jsonArrays) {
        JsonArray mergedJsonArray = new JsonArray();
        for (JsonArray jsonArray : jsonArrays) {
            for (JsonElement jsonElement : jsonArray) {
                mergedJsonArray.add(jsonElement);
            }
        }
        return mergedJsonArray;
    }

    /**
     * 合并JsonArray,不会修改原始的JsonArray数据
     *
     * @param compareKeyInArray 合并数组依据哪个key合并
     * @param jsonArrays
     * @return
     */
    public static JsonArray mergeJsonArraysByKey(String compareKeyInArray, JsonArray... jsonArrays) {
        JsonArray mergedJsonArray = new JsonArray();
        JsonObject mergedJsonObject = new JsonObject();
        for (JsonArray jsonArray : jsonArrays) {
            for (JsonElement jsonElement : jsonArray) {
                JsonObject jsonObject = jsonElement.getAsJsonObject();
                if (jsonObject.has(compareKeyInArray)) {
                    String key = jsonObject.get(compareKeyInArray).getAsString();
                    if (mergedJsonObject.has(key)) {
                        JsonObject existingJsonObject = mergedJsonObject.get(key).getAsJsonObject();
                        for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
                            existingJsonObject.add(entry.getKey(), entry.getValue());
                        }
                    } else {
                        mergedJsonObject.add(key, jsonObject);
                    }
                } else {
                    mergedJsonArray.add(jsonObject);
                }
            }
        }
        for (String key : mergedJsonObject.keySet()) {
            mergedJsonArray.add(mergedJsonObject.get(key));
        }
        return mergedJsonArray;
    }

    /**
     * 合并JsonArray 会修改原始的json数据
     * 如果遇到对象数组，将比较对象数据中的成员
     * 如果 compareKeyInArray 相同，将覆盖，否则将增加
     *
     * @param increase          增量
     * @param original          原始量
     * @param compareKeyInArray 数组中对象成员的指定字段
     * @return 合并后的结果，可能为输入参数或者新量
     */
    private static JsonArray mergeJsonArray(JsonArray increase, JsonArray original, String compareKeyInArray) {
        if (increase == null) {
            return original;
        } else if (original == null) {
            return increase;
        }
        if (StringUtils.isEmpty(compareKeyInArray)) {
            for (int i = 0; i < increase.size(); i++) {
                original.add(increase.get(i));
            }
            return original;
        }
        int increaseSize = increase.size();
        for (int i = 0; i < increaseSize; i++) {
            JsonElement increaseElement = increase.get(i);
            if (!(increaseElement instanceof JsonObject)) {
                original.add(increaseElement);
                continue;
            }
            boolean isSet = false;
            JsonObject increaseObject = increaseElement.getAsJsonObject();
            int originalSize = original.size();
            for (int j = 0; j < originalSize; j++) {
                JsonObject originalObject = original.get(j).getAsJsonObject();
                if (Objects.equals(increaseObject.get(compareKeyInArray), originalObject.get(compareKeyInArray))) {
                    original.set(j, increaseElement);
                    isSet = true;
                    break;
                }
            }
            if (!isSet) {
                original.add(increaseObject);
            }
        }
        return original;
    }


    public static String toJson(Object object) {
        return gson.toJson(object);
    }

    public static <T> T fromJson(String json, Class<T> classOfT) {
        return gson.fromJson(json, classOfT);
    }


}